home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 41 / Amiga Format CD41 (1999-06)(Future Publishing)(GB)[!][issue 1999-07].iso / -seriously_amiga- / misc / jbanner / source / banner.c next >
C/C++ Source or Header  |  1999-04-19  |  11KB  |  517 lines

  1. /* -------------------------------------------------------------------------- *\
  2.    BANNER.C
  3.    Copyright © 1995 by Jarno van der Linden
  4.    jarno@kcbbs.gen.nz
  5.  
  6.    Un*x-like banner generator
  7.  
  8.    This program is Freeware, and all usual Freeware rules apply.
  9.  
  10.    22-Dec-95: Project started
  11.    01-Jan-96: Added ".font" on font names if given name not found
  12.             : Exec version check
  13.    02-Jan-96: V0.9
  14.             : Added environment variable for default settings
  15.             : UPRIGHT switch added
  16.    03-Jan-96: V0.10
  17.             : LEFT, CENTRE, RIGHT flushing switches with WIDTH added
  18.             : Custom drawing characters settings added
  19.             : FILL, NOFILL switches added
  20. \* -------------------------------------------------------------------------- */
  21.  
  22. /* -------------------------------- Includes -------------------------------- */
  23. #include <exec/types.h>
  24. #include <exec/memory.h>
  25. #include <exec/execbase.h>
  26.  
  27. #include <dos/dosextens.h>
  28. #include <dos/rdargs.h>
  29.  
  30. #include <graphics/gfxbase.h>
  31.  
  32. #include <proto/exec.h>
  33. #include <proto/graphics.h>
  34. #include <proto/diskfont.h>
  35. #include <proto/dos.h>
  36.  
  37. #include <string.h>
  38. #include <ctype.h>
  39.  
  40. /* ------------------------------ Definitions ------------------------------- */
  41. #define PROGRAM        "Banner"
  42. #define VERSION        "0.10"
  43. #define DATE        "3.1.96"
  44. #define TEMPLATE    "TEXT/A,SIZE/N,FONT,SIDE=SIDEWAYS/S,UP=UPRIGHT/S,LEFT/S,CENTER=CENTRE/S,RIGHT/S,WIDTH/K/N,CHAR/K,FILLCHAR/K,FILL/S,NOFILL/S"
  45. #define ENVNAME        "Banner_Def"
  46.  
  47. const UBYTE vers[]="\0$VER: "PROGRAM" "VERSION" ("DATE")";
  48.  
  49. enum {
  50.     TEMPLATE_TEXT=0,
  51.     TEMPLATE_SIZE,
  52.     TEMPLATE_FONT,
  53.     TEMPLATE_SIDE,
  54.     TEMPLATE_UP,
  55.     TEMPLATE_LEFT,
  56.     TEMPLATE_CENTRE,
  57.     TEMPLATE_RIGHT,
  58.     TEMPLATE_WIDTH,
  59.     TEMPLATE_CHAR,
  60.     TEMPLATE_FILLCHAR,
  61.     TEMPLATE_FILL,
  62.     TEMPLATE_NOFILL,
  63.     OPT_COUNT
  64. };
  65.  
  66. enum {
  67.     METHOD_UPRIGHT=0,
  68.     METHOD_SIDEWAYS
  69. };
  70.  
  71. enum {
  72.     FLUSH_LEFT=0,
  73.     FLUSH_CENTRE,
  74.     FLUSH_RIGHT
  75. };
  76.  
  77. enum {
  78.     FAIL_OTHER=1,
  79.     FAIL_OPENEXEC,
  80.     FAIL_OPENDOS,
  81.     FAIL_OPENGFX,
  82.     FAIL_OPENDISKFONT,
  83.  
  84.     FAIL_ALLOCRDARGS,
  85.     FAIL_ARGS,
  86.     FAIL_INVALIDSTR,
  87.     FAIL_INVALIDSIZE,
  88.     FAIL_SIDEANDUP,
  89.     FAIL_LEFTCENTRERIGHT,
  90.     FAIL_INVALIDWIDTH,
  91.     FAIL_INVALIDCHAR,
  92.     FAIL_FILLNOFILL,
  93.  
  94.     FAIL_OPENFONT,
  95.     FAIL_RASTPORT,
  96.     FAIL_BITMAP,
  97.     FAIL_BITPLANE,
  98. };
  99.  
  100. /* --------------------------------- Macros --------------------------------- */
  101. #define ERRCHECK        { if(rc) return; }
  102. #define ERRTEST(v,err)        { if(v) { rc=err; return; } }
  103. #define ERREXIT            { ErrorMsg();CleanUp();return(rc?RETURN_ERROR:RETURN_OK); }
  104.  
  105. /* ------------------------------ Proto Types ------------------------------- */
  106. int Banner(void);
  107.  
  108. void CleanUp(void);
  109. void ErrorMsg(void);
  110.  
  111. void OpenLibs(void);
  112. void CloseLibs(void);
  113.  
  114. void SetDefaults(void);
  115. void GetArguments(struct RDArgs *rd);
  116. void GetArgumentsStr(char *str);
  117. void FreeArguments(void);
  118.  
  119. void InitFont(void);
  120. void FreeFont(void);
  121.  
  122. void InitRast(void);
  123. void FreeRast(void);
  124.  
  125. void RenderText(void);
  126. void ScanText(void);
  127.  
  128. void MakeBanner(void);
  129.  
  130. /* -------------------------------- Structs --------------------------------- */
  131.  
  132. /* -------------------------------- Typedefs -------------------------------- */
  133.  
  134. /* -------------------------------- Globals --------------------------------- */
  135. char *errmsg[]={
  136.     NULL,                            // NULL == Use IoErr message
  137.     NULL,                            // FAIL_OTHER;
  138.     "couldn't open Exec library v36\n",            // FAIL_OPENEXEC
  139.     "couldn't open DOS library v36\n",            // FAIL_OPENDOS
  140.     "couldn't open Graphics library v36\n",            // FAIL_OPENGFX
  141.     "couldn't open DiskFont library v36\n",            // FAIL_OPENDISKFONT
  142.  
  143.     "couldn't allocate RDArgs DOS object\n",        // FAIL_ALLOCRDARGS
  144.     NULL,                            // FAIL_ARGS
  145.     "invalid string (must have at least one character)\n",    // FAIL_INVALIDSTR
  146.     "invalid font size (size must be at least 1)\n",    // FAIL_INVALIDSIZE
  147.     "can't specify both SIDEWAYS and UPRIGHT\n",        // FAIL_SIDEANDUP
  148.     "can specify only one of LEFT, CENTRE, RIGHT\n",    // FAIL_LEFTCENTRERIGHT
  149.     "invalid flush width (width must be at least 1)\n",    // FAIL_INVALIDWIDTH
  150.     "invalid draw char (must have one character only)\n",    // FAIL_INVALIDCHAR
  151.     "can't specify both FILL and NOFILL\n",            // FAIL_FILLNOFILL
  152.  
  153.     "couldn't open font\n",                    // FAIL_OPENFONT
  154.     "couldn't allocate rastport\n",                // FAIL_RASTPORT
  155.     "couldn't allocate bitmap\n",                // FAIL_BITMAP
  156.     "couldn't allocate bitplane\n",                // FAIL_BITPLANE
  157. };
  158. int rc=0;
  159.  
  160. struct RDArgs    *rdargs=NULL,
  161.         *strrd=NULL;
  162.  
  163. WORD    textwidth=0,
  164.     textheight=0;
  165. struct RastPort    *rp=NULL;
  166. struct BitMap    *bm=NULL;
  167. struct TextFont    *my_font=NULL;
  168.  
  169. struct ExecBase        *SysBase=NULL;
  170. struct DosLibrary    *DOSBase=NULL;
  171. struct GfxBase        *GfxBase=NULL;
  172. struct Library        *DiskfontBase=NULL;
  173.  
  174. char    *str=NULL;
  175. STRPTR    name=NULL;
  176. long    size=0;
  177. int    method=0;
  178. int    flush=0;
  179. long    width=0;
  180. char    *chr="\0";
  181. char    *fillchr="\0";
  182. BOOL    fill;
  183.  
  184. /* ---------------------------------- Code ---------------------------------- */
  185. int __saveds Banner(void)
  186. {
  187.     OpenLibs();
  188.  
  189.     SetDefaults();
  190.         GetArguments(NULL);
  191.  
  192.     MakeBanner();
  193.  
  194.     ERREXIT;
  195. }
  196.  
  197.  
  198. void CleanUp(void)
  199. {
  200.     FreeArguments();
  201.     CloseLibs();
  202. }
  203.  
  204.  
  205. void ErrorMsg(void)
  206. {
  207.     if(DOSBase) {
  208.         if(errmsg[rc]) {
  209.             Write(Output(),PROGRAM": ",strlen(PROGRAM": "));
  210.             Write(Output(),errmsg[rc],strlen(errmsg[rc]));
  211.         } else if(rc) {
  212.             PrintFault(IoErr(),PROGRAM);
  213.         }
  214.     }
  215. }
  216.  
  217.  
  218. void OpenLibs(void)
  219. {
  220.     ERRCHECK;
  221.  
  222.     SysBase=(*((struct ExecBase **)4));
  223.     ERRTEST(((struct Library *)SysBase)->lib_Version < 36,FAIL_OPENEXEC);
  224.  
  225.     DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",36L);
  226.     ERRTEST(DOSBase==NULL,FAIL_OPENDOS);
  227.  
  228.     GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",36L);
  229.     ERRTEST(GfxBase==NULL,FAIL_OPENGFX);
  230.  
  231.     DiskfontBase=OpenLibrary("diskfont.library",36L);
  232.     ERRTEST(DiskfontBase==NULL,FAIL_OPENDISKFONT);
  233. }
  234.  
  235.  
  236. void CloseLibs(void)
  237. {
  238.     if(DiskfontBase) CloseLibrary(DiskfontBase);
  239.     DiskfontBase=NULL;
  240.  
  241.     if(GfxBase) CloseLibrary((struct Library *)GfxBase);
  242.     GfxBase=NULL;
  243.  
  244.     if(DOSBase) CloseLibrary((struct Library *)DOSBase);
  245.     DOSBase=NULL;
  246. }
  247.  
  248.  
  249. void SetDefaults(void)
  250. {
  251.     char env[256];
  252.     int n;
  253.  
  254.     ERRCHECK;
  255.  
  256.     str=":-)";
  257.     name=GfxBase->DefaultFont->tf_Message.mn_Node.ln_Name;
  258.     size=(long)(GfxBase->DefaultFont->tf_YSize);
  259.     method=METHOD_UPRIGHT;
  260.     flush=FLUSH_LEFT;
  261.     width=80;
  262.     chr="#";
  263.     fillchr=" ";
  264.     fill=FALSE;
  265.  
  266.     n=GetVar(ENVNAME,env,sizeof(env)-sizeof(char)*3,0);
  267.     if(n>0) {
  268.         n=strlen(env);
  269.         env[n]='\n';
  270.         env[n+1]='\0';
  271.         GetArgumentsStr(env);
  272.     }
  273. }
  274.  
  275.  
  276. void GetArguments(struct RDArgs *rd)
  277. {
  278.     long opts[OPT_COUNT];
  279.  
  280.     ERRCHECK;
  281.  
  282.     opts[TEMPLATE_TEXT]=(long)str;
  283.     opts[TEMPLATE_FONT]=(long)name;
  284.     opts[TEMPLATE_SIZE]=(long)&size;
  285.     opts[TEMPLATE_SIDE]=FALSE;
  286.     opts[TEMPLATE_UP]=FALSE;
  287.     opts[TEMPLATE_LEFT]=FALSE;
  288.         opts[TEMPLATE_CENTRE]=FALSE;
  289.         opts[TEMPLATE_RIGHT]=FALSE;
  290.         opts[TEMPLATE_WIDTH]=(long)&width;
  291.         opts[TEMPLATE_CHAR]=(long)chr;
  292.         opts[TEMPLATE_FILLCHAR]=(long)fillchr;
  293.     opts[TEMPLATE_FILL]=FALSE;
  294.     opts[TEMPLATE_NOFILL]=FALSE;
  295.  
  296.     rdargs=ReadArgs(TEMPLATE,opts,rd);
  297.     ERRTEST(rdargs==NULL,FAIL_ARGS);
  298.  
  299.     str  = (char *)(opts[TEMPLATE_TEXT]);
  300.     ERRTEST(strlen(str)<=0,FAIL_INVALIDSTR);
  301.  
  302.     name = (STRPTR)(opts[TEMPLATE_FONT]);
  303.  
  304.     size = (*(long *)(opts[TEMPLATE_SIZE]));
  305.     ERRTEST(size<=0,FAIL_INVALIDSIZE);
  306.  
  307.     ERRTEST(opts[TEMPLATE_SIDE] && opts[TEMPLATE_UP],FAIL_SIDEANDUP);
  308.     if(opts[TEMPLATE_SIDE]) method=METHOD_SIDEWAYS;
  309.     if(opts[TEMPLATE_UP]) method=METHOD_UPRIGHT;
  310.  
  311.     ERRTEST((opts[TEMPLATE_LEFT] && opts[TEMPLATE_CENTRE]) ||
  312.             (opts[TEMPLATE_LEFT] && opts[TEMPLATE_RIGHT]) ||
  313.             (opts[TEMPLATE_CENTRE] && opts[TEMPLATE_RIGHT]),FAIL_LEFTCENTRERIGHT);
  314.     if(opts[TEMPLATE_LEFT]) flush=FLUSH_LEFT;
  315.     if(opts[TEMPLATE_CENTRE]) flush=FLUSH_CENTRE;
  316.     if(opts[TEMPLATE_RIGHT]) flush=FLUSH_RIGHT;
  317.  
  318.     width=(*(long *)(opts[TEMPLATE_WIDTH]));
  319.     ERRTEST(width<=0,FAIL_INVALIDWIDTH);
  320.  
  321.     chr=(char *)opts[TEMPLATE_CHAR];
  322.     ERRTEST(strlen(chr)!=1,FAIL_INVALIDCHAR);
  323.  
  324.     fillchr=(char *)opts[TEMPLATE_FILLCHAR];
  325.     ERRTEST(strlen(fillchr)!=1,FAIL_INVALIDCHAR);
  326.  
  327.     ERRTEST(opts[TEMPLATE_FILL] && opts[TEMPLATE_NOFILL],FAIL_FILLNOFILL);
  328.     if(opts[TEMPLATE_FILL]) fill=TRUE;
  329.     if(opts[TEMPLATE_NOFILL]) fill=FALSE;
  330. }
  331.  
  332.  
  333. void GetArgumentsStr(char *str)
  334. {
  335.     ERRCHECK;
  336.  
  337.     strrd=AllocDosObject(DOS_RDARGS,NULL);
  338.     ERRTEST(strrd==NULL,FAIL_ALLOCRDARGS);
  339.  
  340.     strrd->RDA_Source.CS_Buffer=str;
  341.     strrd->RDA_Source.CS_Length=strlen(str);
  342.     strrd->RDA_Source.CS_CurChr=0;
  343.     strrd->RDA_DAList=NULL;
  344.     strrd->RDA_Buffer=NULL;
  345.     strrd->RDA_BufSiz=0;
  346.     strrd->RDA_ExtHelp=NULL;
  347.     strrd->RDA_Flags=0;
  348.  
  349.     GetArguments(strrd);
  350. }
  351.  
  352.  
  353. void FreeArguments(void)
  354. {
  355.     if(rdargs) FreeArgs(rdargs);
  356.     rdargs=NULL;
  357.     if(strrd) FreeDosObject(DOS_RDARGS,strrd);
  358.     strrd=NULL;
  359. }
  360.  
  361.  
  362. void InitFont(void)
  363. {
  364.     struct TextAttr ta={
  365.         NULL,
  366.         0,
  367.         0,
  368.         NULL
  369.     };
  370.     char fontname[MAXFONTPATH+6];
  371.  
  372.     ERRCHECK;
  373.  
  374.     strncpy(fontname,name,MAXFONTPATH);
  375.  
  376.     ta.ta_Name=fontname;
  377.     ta.ta_YSize=size;
  378.  
  379.     my_font=OpenDiskFont(&ta);
  380.     if(my_font==NULL) {
  381.         strcat(fontname,".font");
  382.         my_font=OpenDiskFont(&ta);
  383.     }
  384.  
  385.     ERRTEST(my_font==NULL,FAIL_OPENFONT);
  386. }
  387.  
  388.  
  389. void FreeFont(void)
  390. {
  391.     if(my_font) CloseFont(my_font);
  392.     my_font=NULL;
  393. }
  394.  
  395.  
  396. void InitRast(void)
  397. {
  398.     struct TextExtent ext;
  399.  
  400.     ERRCHECK;
  401.  
  402.     rp=AllocVec(sizeof(struct RastPort),MEMF_CLEAR | MEMF_PUBLIC);
  403.     ERRTEST(rp==NULL,FAIL_RASTPORT);
  404.  
  405.     InitRastPort(rp);
  406.  
  407.     SetFont(rp,my_font);
  408.     TextExtent(rp,str,strlen(str),&ext);
  409.     textwidth=ext.te_Width;
  410.     textheight=ext.te_Height;
  411.  
  412.     bm=AllocVec(sizeof(struct BitMap),MEMF_CLEAR | MEMF_PUBLIC);
  413.     ERRTEST(bm==NULL,FAIL_BITMAP);
  414.  
  415.     InitBitMap(bm,1,textwidth,textheight);
  416.  
  417.     bm->Planes[0]=AllocRaster(textwidth,textheight);
  418.     ERRTEST(bm->Planes[0]==NULL,FAIL_BITPLANE);
  419.  
  420.     rp->BitMap=bm;
  421. }
  422.  
  423.  
  424. void FreeRast(void)
  425. {
  426.     if(rp) FreeVec(rp);
  427.     rp=NULL;
  428.  
  429.     if(bm) {
  430.         if(bm->Planes[0]) FreeRaster(bm->Planes[0],textwidth,textheight);
  431.         bm->Planes[0]=NULL;
  432.  
  433.         FreeVec(bm);
  434.     }
  435.     bm=NULL;
  436. }
  437.  
  438.  
  439. void RenderText(void)
  440. {
  441.     ERRCHECK;
  442.  
  443.     Move(rp,0,my_font->tf_Baseline);
  444.     Text(rp,str,strlen(str));
  445. }
  446.  
  447.  
  448. void ScanText(void)
  449. {
  450.     WORD x,y;
  451.     LONG textextral,textextrar;
  452.     LONG p;
  453.  
  454.     ERRCHECK;
  455.  
  456.     textextral=textextrar=0;
  457.  
  458.     if(method==METHOD_UPRIGHT) {
  459.         if(flush==FLUSH_CENTRE) {
  460.             textextral=(width-textwidth)/2;
  461.             textextrar=width-textwidth-textextral;
  462.         } else if(flush==FLUSH_RIGHT) {
  463.             textextral=width-textwidth;
  464.         }
  465.         if(textextral < 0) textextral=0;
  466.         if(textextrar < 0) textextrar=0;
  467.  
  468.         for(y=0;y<textheight;y++) {
  469.             for(x=0;x<textextral;x++)
  470.                 FPutC(Output(),fill?fillchr[0]:' ');
  471.             for(x=0;x<textwidth;x++) {
  472.                 p=ReadPixel(rp,x,y);
  473.                 FPutC(Output(),p ? chr[0] : fillchr[0]);
  474.             }
  475.             for(x=0;x<textextrar;x++)
  476.                 FPutC(Output(),fill?fillchr[0]:' ');
  477.             FPutC(Output(),'\n');
  478.         }
  479.     } else if(method==METHOD_SIDEWAYS) {
  480.         if(flush==FLUSH_CENTRE) {
  481.             textextral=(width-textheight)/2;
  482.             textextrar=width-textheight-textextral;
  483.         } else if(flush==FLUSH_RIGHT) {
  484.             textextral=width-textheight;
  485.         }
  486.         if(textextral < 0) textextral=0;
  487.         if(textextrar < 0) textextrar=0;
  488.  
  489.         for(x=0;x<textwidth;x++) {
  490.             for(y=0;y<textextral;y++)
  491.                 FPutC(Output(),fill?fillchr[0]:' ');
  492.             for(y=textheight-1;y>=0;y--) {
  493.                 p=ReadPixel(rp,x,y);
  494.                 FPutC(Output(),p ? chr[0] : fillchr[0]);
  495.             }
  496.             for(y=0;y<textextrar;y++)
  497.                 FPutC(Output(),fill?fillchr[0]:' ');
  498.             FPutC(Output(),'\n');
  499.         }
  500.     }
  501. }
  502.  
  503.  
  504. void MakeBanner(void)
  505. {
  506.     ERRCHECK;
  507.  
  508.     InitFont();
  509.     InitRast();
  510.  
  511.     RenderText();
  512.     ScanText();
  513.  
  514.     FreeRast();
  515.     FreeFont();
  516. }
  517.